#ifndef ELFREAD_H
#define ELFREAD_H

#include <elf.h>
#include <vector>
#include "elf_common.h"
class ELFRead
{
public:
    ELFRead();
    ~ELFRead();
    void updateData(std::string fileName);
    ELF_HEADER getHeaderInfo();
    std::vector<ELF_SHDR> ReadFileSectionHeader();
    std::vector<ELF_PHDR> getFileProgramHeader();
    Elf64_Shdr getSection(int index);
    unsigned char *getBuffer();

private:
    void getFileBuffer();
    //======================================
    Elf64_Ehdr * ReadFileHead();
    std::string getMagicNumber(Elf64_Ehdr *ehdr);
    std::string getObjectFileType(Elf64_Ehdr *ehdr);
    std::string getArchitecture(Elf64_Ehdr *ehdr);
    std::string getObjectFileVersion(Elf64_Ehdr *ehdr);
    std::string getEntryPointVirtualAddress(Elf64_Ehdr *ehdr);
    std::string getProgramHeaderOffset(Elf64_Ehdr *ehdr);
    std::string getSectionHeaderOffset(Elf64_Ehdr *ehdr);
    std::string getProcessorSpecificFlags(Elf64_Ehdr *ehdr);
    std::string getElfHeaderSize(Elf64_Ehdr *ehdr);
    std::string getProgramHeaderSize(Elf64_Ehdr *ehdr);
    std::string getProgramHeaderNumber(Elf64_Ehdr *ehdr);
    std::string getSectionHeaderSize(Elf64_Ehdr *ehdr);
    std::string getSectionHeaderNumber(Elf64_Ehdr *ehdr);
    std::string getSectionHeaderStringTableIndex(Elf64_Ehdr *ehdr);


    // =====================================================
    std::string	getSectionName(const Elf64_Shdr item,const Elf64_Ehdr * ehdr );             /* Section name (string tbl index) */
    std::string	getSectionType(const Elf64_Shdr item);             /* Section type */
    std::string	getSectionFlags(const Elf64_Shdr item);			/* Section flags */
    std::string	getSectionVirtualAddr(const Elf64_Shdr item);		/* Section virtual addr at execution */
    std::string	getSectionOffset(const Elf64_Shdr item);           /* Section file offset */
    std::string	getSectionSize(const Elf64_Shdr item);             /* Section size in bytes */
    std::string	getSectionLink(const Elf64_Shdr item);             /* Link to another section */
    std::string	getSectionInfo(const Elf64_Shdr item);             /* Additional section information */
    std::string	getSectionAlignment(const Elf64_Shdr item);		/* Section alignment */
    std::string	getSectionEntrySize(const Elf64_Shdr item);		/* Entry size if section holds table */

    // =========================================================

    std::string  getSegmentType(Elf64_Phdr item);			/* Segment type */
    std::string  getSegmentOffset(Elf64_Phdr item);		/* Segment file offset */
    std::string  getSegmentVaddr(Elf64_Phdr item);		/* Segment virtual address */
    std::string  getSegmentPaddr(Elf64_Phdr item);		/* Segment physical address */
    std::string  getSegmentFilesz(Elf64_Phdr item);		/* Segment size in file */
    std::string  getSegmentMemsz(Elf64_Phdr item);		/* Segment size in memory */
    std::string  getSegmentFlags(Elf64_Phdr item);		/* Segment flags */
    std::string  getSegmentAlign(Elf64_Phdr item);		/* Segment alignment */

private:
    std::string getAddr(Elf64_Addr addr);
    unsigned char * fileBuffer;
    std::string fileName;
};

#endif // ELFREAD_H
